package au.edu.adelaide.mips_soft_core.board_interface_pc.ui;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.event.TableModelListener;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.table.DefaultTableColumnModel;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;

import au.edu.adelaide.mips_soft_core.board_interface_pc.core.Device;
import au.edu.adelaide.mips_soft_core.board_interface_pc.core.Processor;
import au.edu.adelaide.mips_soft_core.board_interface_pc.core.ProcessorListener;

public class DebuggerPanel extends JPanel{
	
	ArrayList<SystemDebugger> processors = new ArrayList<SystemDebugger>();
	JLabel processorLabel = new JLabel("Processors");
	
	
	public DebuggerPanel(UI ui){
		BoxLayout bl = new BoxLayout(this, BoxLayout.Y_AXIS);
		this.setLayout(bl);
		this.add(new JLabel("Processors"));
	}
	
	void addProcessor(Processor processor){
		SystemDebugger sd = new SystemDebugger(processor);
		this.processors.add(sd);
		this.add(sd);
	}
	
	void clear(){
		for(int i = 0; i < this.processors.size(); i++){
			SystemDebugger sd = this.processors.get(i);
			sd.processor.removeProcessorListener(sd);
		}
		this.processors.clear();
	}
	
	public static class SystemDebugger extends JPanel implements ProcessorListener, ActionListener{
		
		JButton runPause = new JButton("Run");
		JButton step = new JButton("Step");
		JLabel pcLabel = new JLabel("Program Counter:");
		JButton refresh = new JButton("Refresh");
		JTextField pc = new JTextField(10);
		
		Processor processor;
		
		JLabel label;
		JTable table;
		RegisterTable rt;
		
		JButton treeButton;
		
		JPanel mainPanel;
		
		
		public SystemDebugger(Processor processor){
			super(new BorderLayout());
			{
				JPanel topPanel = new JPanel(new BorderLayout());
				treeButton = new JButton("-");
				treeButton.addActionListener(this);
				topPanel.add(treeButton, BorderLayout.WEST);
				topPanel.add(new JLabel("Processor: " + processor.processorNumber));
				this.add(topPanel, BorderLayout.NORTH);
			}
			{
				mainPanel = new JPanel(new BorderLayout());
				this.pc.setEditable(false);
				this.label  = new JLabel("Processor: "+ processor.processorNumber);
				JPanel temp = new JPanel();
				temp.add(runPause);
				temp.add(step);
				temp.add(pcLabel);
				temp.add(pc);
				temp.add(refresh);
				rt = new RegisterTable(processor);
				this.table = new JTable(rt);
				this.table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
				this.table.setPreferredSize(new Dimension(600, 400));
				this.processor = processor;
				this.processor.addProcessorListener(this);
				this.refresh.addActionListener(this);
				this.step.addActionListener(this);
				mainPanel.add(temp, BorderLayout.NORTH);
				mainPanel.add(new JScrollPane(this.table), BorderLayout.CENTER);
				this.add(mainPanel, BorderLayout.CENTER);
			}
			
		}

		@Override
		public void PCChanged() {
			this.pc.setText(String.format("%08X", this.processor.pc) + " <=> " + Integer.toString(this.processor.pc));
		}

		@Override
		public void registerChanged() {
			this.rt.notifyListeners();
		}

		@Override
		public void outDated() {
			this.processor.getPCAndRegisters();
		}
		
		@Override
		public void actionPerformed(ActionEvent event) {
			if(event.getSource() == this.refresh){
				this.processor.getPCAndRegisters();
			}else if(event.getSource() == this.step){
				this.processor.step();
			}else if(event.getSource() == this.treeButton){
				if(this.treeButton.getText().equals("-")){
					this.treeButton.setText("+");
					this.mainPanel.setVisible(false);
				}else{
					this.treeButton.setText("-");
					this.mainPanel.setVisible(true);
				}
			}
		}
		
		
		
	}



}
